package cn.mjnxin.iot.gate.coder;

import cn.mjnxin.iot.base.constant.ConstantValue;
import cn.mjnxin.iot.base.domain.ChannelData;
import cn.mjnxin.iot.base.domain.GatePacketWriter;
import cn.mjnxin.iot.base.domain.SocketData;
import cn.mjnxin.iot.base.log.LogWorker;
import cn.mjnxin.iot.base.util.CommonUtil;
import cn.mjnxin.iot.gate.cache.GateRuntimeCache;
import cn.mjnxin.iot.transfer.TransferExchange;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

/**
 * 编码器 将对象 编码成字节数组  -->目的地是前置服务

 * @author CLG 2023年10月10日
 * @version V1.0.0
 */
public class Gate2HostEncoder extends MessageToByteEncoder<ChannelData>{
	// 日志等级 0：无日志 1：报文长度日志 2：报文内容日志 3：所有日志
	private int logLevel = 0;

	public Gate2HostEncoder(int logLevel) {
		this.logLevel  = logLevel;
	}
	
    /**
     * 当前ChannelHandlerContext  是与前置相连的channel的上下文
     */
    @Override
    protected void encode(ChannelHandlerContext ctx, ChannelData msg, ByteBuf out) throws Exception {
        try {
            /**
             * 组网关报头
             */
            String terminalAddress = msg.getTerminalAddress();
            // count 前置与网关建立连接时对应的连接序号（1-10000循环）
            int count = GateRuntimeCache.getCount(terminalAddress);

            String hostAddress = msg.getHostAddress();
            SocketData data = msg.getSocketData();
            
            ByteBuf toHostBuf = data.getByteBuf();
            int length = toHostBuf.readableBytes();
            GatePacketWriter headBuf = TransferExchange.packHead(GateRuntimeCache.gateNo, ConstantValue.TYPE_TERMINAL_TO_HOST, terminalAddress, data.getPid(), logLevel, count, length);
    
            out.writeBytes(headBuf.getDataBuffer());
            // 真实报文
            out.writeBytes(toHostBuf);
			if (logLevel == 1) {
				if (terminalAddress == null) {
					LogWorker.logForce(String.format("%d|G->H[%s]=%d Bytes", msg.getPid(), hostAddress, out.readableBytes()));
				}
				else {
					LogWorker.logForce(String.format("%d|T[%s]->G->H[%s]=%d Bytes", msg.getPid(), terminalAddress, hostAddress, out.readableBytes()));
				}
            }
            else if (logLevel >= 2) {
				if (terminalAddress == null) {
					LogWorker.logForce(String.format("%d|G->H[%s]=", msg.getPid(), hostAddress), out);
				}
				else {
					LogWorker.logForce(String.format("%d|T[%s]->G->H[%s]=", msg.getPid(), terminalAddress, hostAddress), out);
				}
            }
        }
        finally {
            CommonUtil.releaseData(msg);
        }
    }
}
